package org.example.demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.example.demo.model.CommonResponse;
import org.example.demo.model.bo.GoodsCreateGoodsInputBO;
import org.example.demo.model.bo.GoodsDeleteGoodsInputBO;
import org.example.demo.model.bo.GoodsGetGoodsInputBO;
import org.example.demo.model.bo.GoodsUpdateGoodsInputBO;
import org.example.demo.service.GoodsService;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("/api/goods")
@Slf4j
@CrossOrigin(origins = "*", maxAge = 3600)
public class GoodsController {

    @Autowired
    private GoodsService goodsService;
    
    // 使用内存缓存存储商品原始创建数据
    private static final Map<String, Map<String, Object>> GOODS_CACHE = new ConcurrentHashMap<>();

    @PostMapping("/create")
    public CommonResponse createGoods(@RequestBody Map<String, Object> requestMap) {
        try {
            log.info("创建商品请求参数: {}", requestMap);
            
            // 从请求Map中提取字段并转换类型
            GoodsCreateGoodsInputBO input = new GoodsCreateGoodsInputBO();
            
            // 处理ID
            BigInteger id = null;
            if (requestMap.get("_id") != null) {
                id = new BigInteger(requestMap.get("_id").toString());
                input.set_id(id);
            }
            
            // 处理名称
            if (requestMap.get("_name") != null) {
                input.set_name(requestMap.get("_name").toString());
            }
            
            // 处理描述
            if (requestMap.get("_desc") != null) {
                input.set_desc(requestMap.get("_desc").toString());
            }
            
            // 处理价格
            if (requestMap.get("_price") != null) {
                input.set_price(new BigInteger(requestMap.get("_price").toString()));
            }
            
            log.info("构造的商品输入对象: {}", input);
            
            TransactionResponse response = goodsService.createGoods(input);
            log.info("创建商品交易响应: {}", response);
            
            // 缓存商品数据，以ID为键
            if (id != null) {
                // 存储原始输入数据
                GOODS_CACHE.put(id.toString(), new HashMap<>(requestMap));
                log.info("缓存商品数据: ID={}, 数据={}", id, requestMap);
            }
            
            Map<String, Object> result = new HashMap<>();
            TransactionReceipt receipt = response.getTransactionReceipt();
            result.put("transactionHash", receipt.getTransactionHash());
            result.put("blockNumber", receipt.getBlockNumber());
            result.put("status", receipt.getStatus());
            result.put("from", receipt.getFrom());
            result.put("to", receipt.getTo());
            
            log.info("创建商品成功，交易详情: {}", result);
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("Create goods error", e);
            return CommonResponse.fail("1001", e);
        }
    }

    @PutMapping("/update")
    public CommonResponse updateGoods(@RequestBody Map<String, Object> requestMap) {
        try {
            log.info("更新商品请求参数: {}", requestMap);
            
            // 从请求Map中提取字段并转换类型
            GoodsUpdateGoodsInputBO input = new GoodsUpdateGoodsInputBO();
            
            // 处理ID
            BigInteger id = null;
            if (requestMap.get("_id") != null) {
                id = new BigInteger(requestMap.get("_id").toString());
                input.set_id(id);
            }
            
            // 处理名称
            if (requestMap.get("_name") != null) {
                input.set_name(requestMap.get("_name").toString());
            }
            
            // 处理描述
            if (requestMap.get("_desc") != null) {
                input.set_desc(requestMap.get("_desc").toString());
            }
            
            // 处理价格
            if (requestMap.get("_price") != null) {
                input.set_price(new BigInteger(requestMap.get("_price").toString()));
            }
            
            log.info("构造的商品更新对象: {}", input);
            
            TransactionResponse response = goodsService.updateGoods(input);
            log.info("更新商品交易响应: {}", response);
            
            // 更新缓存
            if (id != null) {
                // 如果缓存中存在此商品，更新数据
                if (GOODS_CACHE.containsKey(id.toString())) {
                    Map<String, Object> cachedGoods = GOODS_CACHE.get(id.toString());
                    for (Map.Entry<String, Object> entry : requestMap.entrySet()) {
                        cachedGoods.put(entry.getKey(), entry.getValue());
                    }
                    log.info("更新缓存商品数据: ID={}, 数据={}", id, cachedGoods);
                } else {
                    // 不存在则新建
                    GOODS_CACHE.put(id.toString(), new HashMap<>(requestMap));
                    log.info("缓存新商品数据: ID={}, 数据={}", id, requestMap);
                }
            }
            
            Map<String, Object> result = new HashMap<>();
            TransactionReceipt receipt = response.getTransactionReceipt();
            result.put("transactionHash", receipt.getTransactionHash());
            result.put("blockNumber", receipt.getBlockNumber());
            result.put("status", receipt.getStatus());
            result.put("from", receipt.getFrom());
            result.put("to", receipt.getTo());
            
            log.info("更新商品成功，交易详情: {}", result);
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("Update goods error", e);
            return CommonResponse.fail("1002", e);
        }
    }

    @DeleteMapping("/{id}")
    public CommonResponse deleteGoods(@PathVariable("id") String idStr) {
        try {
            log.info("删除商品ID: {}", idStr);
            
            BigInteger id = new BigInteger(idStr);
            GoodsDeleteGoodsInputBO input = new GoodsDeleteGoodsInputBO(id);
            
            TransactionResponse response = goodsService.deleteGoods(input);
            log.info("删除商品交易响应: {}", response);
            
            // 从缓存中移除该商品
            GOODS_CACHE.remove(idStr);
            log.info("从缓存中移除商品: ID={}", idStr);
            
            Map<String, Object> result = new HashMap<>();
            TransactionReceipt receipt = response.getTransactionReceipt();
            result.put("transactionHash", receipt.getTransactionHash());
            result.put("blockNumber", receipt.getBlockNumber());
            result.put("status", receipt.getStatus());
            result.put("from", receipt.getFrom());
            result.put("to", receipt.getTo());
            
            log.info("删除商品成功，交易详情: {}", result);
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("Delete goods error", e);
            return CommonResponse.fail("1003", e);
        }
    }

    @GetMapping("/{id}")
    public CommonResponse getGoods(@PathVariable("id") String idStr) {
        try {
            log.info("获取商品详情ID: {}", idStr);
            
            BigInteger id = new BigInteger(idStr);
            GoodsGetGoodsInputBO input = new GoodsGetGoodsInputBO(id);
            
            CallResponse response = goodsService.getGoods(input);
            log.info("获取商品详情响应: {}, values={}", response, response.getValues());
            
            if (response.getValues() == null || response.getValues().isEmpty()) {
                log.warn("商品ID {} 不存在或返回值为空", id);
                return CommonResponse.ok(null);
            }
            
            // 优先从缓存中获取商品数据
            Map<String, Object> cachedData = GOODS_CACHE.get(idStr);
            if (cachedData != null) {
                log.info("从缓存中获取商品数据: ID={}, 数据={}", idStr, cachedData);
                
                // 构造结果对象
                Map<String, Object> result = new HashMap<>();
                result.put("id", id);
                
                // 从缓存中提取名称、描述和价格
                Map<String, Object> formattedData = new HashMap<>();
                formattedData.put("name", cachedData.get("_name"));
                formattedData.put("description", cachedData.get("_desc"));
                formattedData.put("price", cachedData.get("_price"));
                
                result.put("formattedData", formattedData);
                
                // 同时保留原始区块链返回数据以便调试
                result.put("responseData", response.getValues());
                
                log.info("返回缓存的商品数据: {}", result);
                return CommonResponse.ok(result);
            }
            
            // 如果没有找到缓存数据，则使用传统方式解析区块链返回的数据
            Map<String, Object> result = new HashMap<>();
            result.put("id", id);
            
            // 处理响应数据
            Object responseData = response.getValues();
            
            // 如果responseData是字符串或其他格式，尝试提取商品信息
            if (responseData != null) {
                try {
                    // 直接构造格式化的商品信息
                    Map<String, Object> formattedData = new HashMap<>();
                    
                    // 尝试从responseData提取商品名称、描述和价格
                    List<Object> goodsInfo = null;
                    
                    if (responseData instanceof List) {
                        goodsInfo = (List<Object>) responseData;
                    } else if (responseData instanceof String) {
                        // 尝试移除多余的括号和引号
                        String cleanedData = responseData.toString()
                            .replaceAll("\\[\\[|\\]\\]", "")  // 移除双层方括号
                            .replaceAll("\\\\\"", "")        // 移除转义引号
                            .replaceAll("^\"|\"$", "");      // 移除首尾引号
                        
                        // 如果是JSON格式，尝试解析
                        if (cleanedData.startsWith("[") && cleanedData.endsWith("]")) {
                            // 简单处理：分割字符串
                            String[] parts = cleanedData.substring(1, cleanedData.length() - 1)
                                .split(",");
                            
                            goodsInfo = new ArrayList<>();
                            for (String part : parts) {
                                goodsInfo.add(part.trim().replaceAll("^\"|\"$", ""));
                            }
                        }
                    }
                    
                    if (goodsInfo != null && goodsInfo.size() >= 3) {
                        // 提取商品信息
                        formattedData.put("name", goodsInfo.get(0).toString().replaceAll("^\"|\"$", ""));
                        formattedData.put("description", goodsInfo.get(1).toString().replaceAll("^\"|\"$", ""));
                        formattedData.put("price", goodsInfo.get(2).toString().replaceAll("^\"|\"$|￥", ""));
                        
                        // 返回格式化后的数据
                        result.put("formattedData", formattedData);
                        log.info("格式化后的商品数据: {}", formattedData);
                    }
                } catch (Exception e) {
                    log.error("格式化商品数据出错", e);
                }
            }
            
            // 同时保留原始数据以便调试
            result.put("responseData", responseData);
            
            log.info("获取商品详情成功: {}", result);
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("Get goods error", e);
            return CommonResponse.fail("1004", e);
        }
    }

    @GetMapping("/list")
    public CommonResponse getAllGoods() {
        try {
            log.info("获取所有商品ID列表");
            
            CallResponse response = goodsService.getAllGoodsIds();
            log.info("获取所有商品ID列表响应: {}, values={}", response, response.getValues());
            
            if (response.getValues() == null || response.getValues().isEmpty()) {
                log.info("商品列表为空");
                return CommonResponse.ok(new ArrayList<>());
            }
            
            // 直接返回响应信息
            Object result = response.getValues();
            
            // 如果返回值是一个字符串，尝试手动解析
            if (result instanceof String) {
                String resultStr = (String) result;
                log.info("商品ID列表是字符串格式: {}", resultStr);
                
                // 尝试移除JSON数组格式的前后括号和引号
                resultStr = resultStr.replaceAll("^\\[|\\]$", "").trim();
                
                // 如果字符串以"["开头和"]"结尾，可能是返回了JSON字符串形式的数组
                if (resultStr.startsWith("[") && resultStr.endsWith("]")) {
                    log.info("尝试解析JSON数组字符串: {}", resultStr);
                    return CommonResponse.ok(resultStr);
                }
                
                // 否则可能是逗号分隔的ID列表
                String[] idStrings = resultStr.split(",");
                List<BigInteger> ids = new ArrayList<>();
                
                for (String idStr : idStrings) {
                    if (idStr != null && !idStr.trim().isEmpty()) {
                        try {
                            ids.add(new BigInteger(idStr.trim()));
                        } catch (NumberFormatException e) {
                            log.warn("无法解析商品ID字符串: {}", idStr, e);
                        }
                    }
                }
                
                log.info("解析后的商品ID列表: {}", ids);
                return CommonResponse.ok(ids);
            }
            
            log.info("返回原始商品ID列表: {}", result);
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("Get all goods error", e);
            return CommonResponse.fail("1005", e);
        }
    }

    @GetMapping("/total")
    public CommonResponse getTotalGoods() {
        try {
            log.info("获取商品总数");
            
            CallResponse response = goodsService.totalGoods();
            log.info("获取商品总数响应: {}, values={}", response, response.getValues());
            
            if (response.getValues() == null || response.getValues().isEmpty()) {
                log.info("商品总数为零");
                return CommonResponse.ok(0);
            }
            
            // 直接返回响应信息
            Object result = response.getValues();
            log.info("商品总数结果: {}", result);
            
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("Get total goods error", e);
            return CommonResponse.fail("1006", e);
        }
    }

    @GetMapping("/contract/{id}")
    public CommonResponse getGoodsFromContract(@PathVariable("id") String idStr) {
        try {
            log.info("直接从智能合约获取商品ID: {}", idStr);
            
            BigInteger id = new BigInteger(idStr);
            GoodsGetGoodsInputBO input = new GoodsGetGoodsInputBO(id);
            
            // 记录请求时间
            long startTime = System.currentTimeMillis();
            CallResponse response = goodsService.getGoods(input);
            long endTime = System.currentTimeMillis();
            
            log.info("合约查询响应: {}, values={}, 耗时={}ms", response, response.getValues(), (endTime - startTime));
            
            if (response.getValues() == null || response.getValues().isEmpty()) {
                log.warn("商品ID {} 在合约中不存在或返回值为空", id);
                return CommonResponse.fail("2002", "商品不存在或数据为空");
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("id", id);
            
            // 处理合约响应数据
            Object responseData = response.getValues();
            
            if (responseData != null) {
                try {
                    // 格式化合约返回的数据
                    Map<String, Object> contractData = new HashMap<>();
                    
                    // 从智能合约直接获取的数据通常是一个数组结构
                    // 合约方法: function getGoods(uint _id) returns (string name, string description, uint price)
                    if (responseData instanceof List) {
                        List<Object> goodsData = (List<Object>) responseData;
                        log.info("合约返回的数据是List类型，大小为: {}, 内容: {}", goodsData.size(), goodsData);
                        
                        if (goodsData.size() >= 3) {
                            // 第1个元素是商品名称
                            String name = goodsData.get(0).toString();
                            // 第2个元素是商品描述
                            String description = goodsData.get(1).toString();
                            // 第3个元素是商品价格
                            String price = goodsData.get(2).toString();
                            
                            log.info("提取到原始数据 - 名称: {}, 描述: {}, 价格: {}", name, description, price);
                            
                            // 清理特殊字符
                            name = name.replaceAll("[\\[\\]\"']", "").trim();
                            description = description.replaceAll("[\\[\\]\"']", "").trim();
                            
                            contractData.put("name", name);
                            contractData.put("description", description);
                            contractData.put("price", price);
                            
                            log.info("清理后的商品数据: {}", contractData);
                            result.put("contractData", contractData);
                        } else {
                            log.warn("合约返回数据元素不足，只有 {} 个元素", goodsData.size());
                        }
                    } else if (responseData instanceof String) {
                        log.info("合约返回的数据是String类型: {}", responseData);
                        // 尝试解析字符串格式的响应
                        String responseStr = (String) responseData;
                        
                        // 如果是JSON字符串，尝试解析为数组
                        if (responseStr.startsWith("[") && responseStr.endsWith("]")) {
                            try {
                                // 移除外层括号
                                String cleanedStr = responseStr.substring(1, responseStr.length() - 1);
                                // 按逗号分割
                                String[] parts = cleanedStr.split(",");
                                
                                if (parts.length >= 3) {
                                    // 清理并提取数据
                                    String name = parts[0].replaceAll("[\\[\\]\"']", "").trim();
                                    String description = parts[1].replaceAll("[\\[\\]\"']", "").trim();
                                    String price = parts[2].replaceAll("[\\[\\]\"']", "").trim();
                                    
                                    contractData.put("name", name);
                                    contractData.put("description", description);
                                    contractData.put("price", price);
                                    
                                    log.info("从字符串解析的商品数据: {}", contractData);
                                    result.put("contractData", contractData);
                                } else {
                                    log.warn("从字符串解析的数据元素不足，只有 {} 个元素", parts.length);
                                }
                            } catch (Exception e) {
                                log.error("解析字符串格式响应失败", e);
                            }
                        }
                    } else {
                        log.warn("合约返回的数据类型未知: {}", responseData.getClass().getName());
                    }
                } catch (Exception e) {
                    log.error("处理合约返回数据出错", e);
                }
            }
            
            // 保留原始数据以便调试
            result.put("rawData", responseData);
            
            // 检查是否成功提取到商品数据
            if (!result.containsKey("contractData")) {
                log.error("无法从响应中提取商品数据");
                return CommonResponse.fail("2003", "无法解析商品数据");
            }
            
            log.info("合约查询成功: {}", result);
            return CommonResponse.ok(result);
        } catch (Exception e) {
            log.error("合约查询错误", e);
            return CommonResponse.fail("2001", "合约查询失败: " + e.getMessage());
        }
    }
} 